﻿using System;
using Microsoft.Xna.Framework;

namespace Babylon.Animations
{
    public class MatrixAnimation : DurationBasedAnimation, IMatrixAnimation
    {

        public MatrixAnimation()
        {
            this.EasingFunction = Easing.Linear;
        }

        private Matrix _baseValue;
        public Matrix BaseValue
        {
            get { return _baseValue; }
            set
            {
                _baseValue = value;
                UpdateCurrentValue();
            }
        }

        private void UpdateCurrentValue()
        {
            if (AnimationState == AnimationState.Stopped)
                _currentValue = _baseValue;
            else
            {
                var normalizedTime = NormalizedAnimationTime;
                if (normalizedTime >= 1)
                {
                    Matrix.Lerp(ref _baseValue, ref _toValue, EasingFunction(1), out _currentValue);
                    if(AnimationState == AnimationState.Running && !RepeatForever && !AutoReverse)
                        Pause(CurrentTime);
                }
                else
                {
                    Matrix.Lerp(ref _baseValue, ref _toValue, EasingFunction(normalizedTime), out _currentValue);
                }
            }
        }

        protected override void OnPaused()
        {
            base.OnPaused();
            UpdateCurrentValue();
        }

        protected override void OnResumed()
        {
            base.OnResumed();
            UpdateCurrentValue();
        }
        protected override void OnStarted()
        {
            base.OnStarted();
            UpdateCurrentValue();
        }
        protected override void OnStopped()
        {
            base.OnStopped();
            UpdateCurrentValue();
        }
        protected override void OnUpdated()
        {
            base.OnUpdated();
            if (AnimationState == AnimationState.Running)
                UpdateCurrentValue();
        }

        private Matrix _currentValue;
        public Matrix CurrentValue
        {
            get { return _currentValue; }
        }

        private Matrix _toValue;
        public Matrix ToValue
        {
            get { return _toValue; }
            set
            {
                _toValue = value;
                UpdateCurrentValue();
            }
        }

        public EasingFunction EasingFunction { get; set; }
    }
}
